package tests.model_tests;

import org.junit.*;
import static org.junit.Assert.*;
import application.models.datalayer.DataCondition;
import application.models.datalayer.Operator;

/**
 * This class tests the DataCondition interface
 * 
 * @author Morten F. Therkildsen & Philip J. Rasmussen
 */
public class DataCondition_test {
	
	private String attribute_null = null, attribute_empty = "", attribute_one = "test_one", attribute_two = "test_two";
	private Object referenceValue_null = null, referenceValue = 10;
	private Operator operator_equals = Operator.EQUALS, operator_less = Operator.LESS, operator_null;
	private DataCondition dataConditionOne, dataConditionTwo;
	private Exception NullPointerException = new NullPointerException(), IllegalArgumentException = new IllegalArgumentException();
	private boolean properExceptionCast = false;
	
	@Test
	public void nullAttributeName(){
		properExceptionCast = testHelper(NullPointerException , attribute_null, operator_equals, referenceValue_null);
		if(properExceptionCast) return;
		else fail("NullPointerException was not thrown.");
		
		System.out.println("hej");
	}
	
	@Test
	public void emptyAttributeName(){
		properExceptionCast = testHelper(IllegalArgumentException , attribute_empty, operator_equals, referenceValue_null);
		if(properExceptionCast) return;
		else fail("IllegalArgumentException was not thrown.");
	}
	
	@Test
	public void nullOperator(){
		properExceptionCast = testHelper(NullPointerException , attribute_null, operator_null, referenceValue_null);
		if(properExceptionCast) return;
		else fail("NullPointerException was not thrown.");
	}
	
	@Test
	public void getters(){
		testHelper(null, attribute_one, operator_equals, referenceValue_null);
		assertEquals("attributeNames are not equal", dataConditionOne.getAttributeName(), attribute_one);
		assertEquals("operators are not equal", dataConditionOne.getOperator(), Operator.EQUALS);
		assertEquals("operatorValues are not equal", dataConditionOne.getReferenceValue(), referenceValue_null);
	}
	
	@Test
	public void equals(){
		
		//negative
		testHelper(null, attribute_one, operator_equals, referenceValue_null);
		testHelper(null, attribute_one, operator_equals, referenceValue);		
		assertFalse("objects are equal", dataConditionOne.equals(dataConditionTwo));
		
		testHelper(null, attribute_one, operator_equals, referenceValue_null);
		testHelper(null, attribute_one, operator_less, referenceValue_null);		
		assertFalse("objects are equal", dataConditionOne.equals(dataConditionTwo));
		
		testHelper(null, attribute_one, operator_equals, referenceValue_null);
		testHelper(null, attribute_two, operator_equals, referenceValue);		
		assertFalse("objects are equal", dataConditionOne.equals(dataConditionTwo));
		
		//positive
		testHelper(null, attribute_one, operator_equals, referenceValue_null);
		testHelper(null, attribute_one, operator_equals, referenceValue_null);		
		assertEquals("objects are equal", dataConditionOne.equals(dataConditionTwo), false);
	}	
	
	/**
	 * A method to reduce code duplication.
	 * 
	 * @param ex	The expected exception to be thrown
	 * @param attributeName	The attribute for which the condition should apply
	 * @param operator	Whether the attribute should be less than, equal to, or higher than the referenceValue
	 * @param referenceValue	The reference value the attribute should be compared to
	 * @return True if the exception ex has been caught. false if not.
	 */
	private boolean testHelper(Exception ex, String attributeName, Operator operator, Object referenceValue){
		try{
			dataConditionOne = new DataCondition(attributeName, operator, referenceValue);
		} catch(Exception e){ 
			if(e.getClass().isInstance(ex)) return true;
			else return false;
		}
		return false;
	}
}
